/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package ortus.onlinescrapper.themoviedb;

import java.util.HashMap;
import java.util.Iterator;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;
import javax.xml.stream.events.Attribute;
import ortus.onlinescrapper.tools.XMLHelper;
import ortus.onlinescrapper.tools.database;

/**
 *
 * @author jphipps
 */
public class TheMovieDB extends ortus.ortusvars {
	int searchLimit = 5;
	GoogleProvider gp = null;
	IMDBProvider ip = null;
	TMDBProvider tp = null;

public TheMovieDB() {
	gp = new GoogleProvider();
	ip = new IMDBProvider();
	tp = new TMDBProvider();
}

public void SetSearchLimit(int searchLimit) {
	this.searchLimit = searchLimit;
}

public HashMap<String,String> Search(String title) {
	long t0 = System.currentTimeMillis();
	HashMap<String,String> results = new HashMap<String,String>();
	HashMap<String,String> gresults = new HashMap<String,String>();
	HashMap<String,String> tresults = new HashMap<String,String>();
	HashMap<String,String> iresults = new HashMap<String,String>();
	gresults = gp.Search(title, searchLimit);
	tresults = tp.Search(title,searchLimit);
	iresults = ip.Search(title, searchLimit);

	Object[] hk = iresults.keySet().toArray();
	for ( Object x : hk )
		results.put((String)x,iresults.get(x));
	hk = gresults.keySet().toArray();
	for ( Object x : hk )
		results.put((String)x,gresults.get(x));
	hk = tresults.keySet().toArray();
	for ( Object x : hk )
		results.put((String)x,tresults.get(x));
	
	long ttotal = System.currentTimeMillis() - t0;
	ortus.api.DebugLog(TRACE, "TheMovieDB: Search returned " + results.size() + " in " + ttotal + " ms");

	return results;
}

    public Movie GetDetail(String key) {
	ortus.api.DebugLog(TRACE2,"GetDetail: " + key);
	Movie cacheitem = null;
	String[] keyparts = key.split(":");
	if ( keyparts[0].equals("imdb")) {
            cacheitem = database.GetCacheMetadataIMDB(keyparts[1]);
   	    if ( cacheitem != null )
		return cacheitem;
	    cacheitem = GetItemDetailByIMDB(keyparts[1]);
	    if ( cacheitem.GetIMDBId().isEmpty())
		    cacheitem = ip.GetItemDetailByIMDB(keyparts[1]);
	} else if ( keyparts[0].equals("themoviedb")) {
            cacheitem = database.GetCacheMetadataTMDB(keyparts[1]);
   	    if ( cacheitem != null )
		return cacheitem;
	    cacheitem = GetItemDetailByTMDB(keyparts[1]);
	    if ( ! cacheitem.GetIMDBId().isEmpty()) {
		    Movie tempmovie = ip.GetItemDetailByIMDB(cacheitem.GetIMDBId());
		    if ( ! tempmovie.GetRated().isEmpty())
			    cacheitem.SetRated(tempmovie.GetRated());
		    if ( cacheitem.GetCast().size() == 0) {
			    for ( CastItem ci : tempmovie.GetCast()) {
				    cacheitem.AddCast(ci.GetName(), ci.GetJob(), ci.GetCharacter(), ci.GetThumb(), ci.GetUrl());
			    }
		    }
	    }
	}

        database.cacheMetadata(cacheitem);

        return cacheitem;
    }

public Movie GetItemDetailByIMDB(String imdbid) {
//	Movie cacheitem = database.GetCacheMetadataIMDB(imdbid);
//        if ( cacheitem != null )
//            return cacheitem;
	return GetItemDetail("http://api.themoviedb.org/2.1/Movie.imdbLookup/en/xml/6d89df83f02af2b3b712a9e63f8be6fb/" + imdbid);
}

public Movie GetItemDetailByTMDB(String tmdbid) {
//	Movie cacheitem = database.GetCacheMetadataTMDB(tmdbid);
//        if ( cacheitem != null )
//            return cacheitem;
	return GetItemDetail("http://api.themoviedb.org/2.1/Movie.getInfo/en/xml/6d89df83f02af2b3b712a9e63f8be6fb/" + tmdbid);
}

private Movie GetItemDetail(String url) {
	Movie movie = null;
	XMLEventReader xmlReader = null;

	try {
		xmlReader = XMLHelper.getEventReaderUrl(url);

		ortus.api.DebugLog(TRACE2,"Getting ready to parse from url: " + url);
		movie = parseNextMovie(xmlReader);
		if ( movie == null)
			return new Movie();
	} catch (Exception error) {
		ortus.api.DebugLog(ERROR,"TheMovieDB: GetItemDetail: Exception: " + error.getMessage());
		return new Movie();
	} finally {
		XMLHelper.closeEventReader(xmlReader);
	}
	return movie;

}

public static Movie parseNextMovie(XMLEventReader xmlReader) throws XMLStreamException {
	Movie movie = null;

	while (xmlReader.hasNext()) {

	    XMLEvent event = xmlReader.nextEvent();

	    if (event.isStartElement()) {

		StartElement se = event.asStartElement();
		String tag = se.getName().getLocalPart();
//		ortus.api.DebugLog(TRACE2,"parsing tag: " + tag);
		if (tag.equalsIgnoreCase("movies")) {
		    movie = new Movie();
		} else if (tag.equalsIgnoreCase("name")) {
		    movie.SetName(XMLHelper.getCData(xmlReader));
		} else if (tag.equalsIgnoreCase("alternate_name")) {
		    movie.SetAlternateName(XMLHelper.getCData(xmlReader));
		} else if (tag.equalsIgnoreCase("type")) {
		    movie.SetType(XMLHelper.getCData(xmlReader));
		} else if (tag.equalsIgnoreCase("id")) {
		    movie.SetId(XMLHelper.getCData(xmlReader));
		} else if (tag.equalsIgnoreCase("overview")) {
		    movie.SetOverview(XMLHelper.getCData(xmlReader));
		} else if (tag.equalsIgnoreCase("rating")) {
		    movie.SetRating(Float.parseFloat(XMLHelper.getCData(xmlReader)));
		} else if (tag.equalsIgnoreCase("released")) {
		    movie.SetReleaseDate(XMLHelper.getCData(xmlReader));
		} else if (tag.equalsIgnoreCase("runtime")) {
		    movie.SetRunTime(XMLHelper.getCData(xmlReader));
		} else if (tag.equalsIgnoreCase("trailer")) {
		    movie.SetTrailer(XMLHelper.getCData(xmlReader));
		} else if (tag.equalsIgnoreCase("imdb_id")) {
		    movie.SetIMDBId(XMLHelper.getCData(xmlReader));
		} else if (tag.equalsIgnoreCase("url")) {
		    movie.SetUrl(XMLHelper.getCData(xmlReader));
		} else if (tag.equalsIgnoreCase("category")) {
			Iterator<Attribute> attributes = se.getAttributes();
			while (attributes.hasNext()) {
				Attribute attribute = attributes.next();
				if (attribute.getName().toString().equals("name"))
				   movie.AddGenre(attribute.getValue());
			}
		} else if (tag.equalsIgnoreCase("image")) {
			String itype = null;
			String isize = null;
			String iurl = null;
			Iterator<Attribute> attributes = se.getAttributes();
			while (attributes.hasNext()) {
				Attribute attribute = attributes.next();
				if (attribute.getName().toString().equals("type"))
				   itype = attribute.getValue();
				if (attribute.getName().toString().equals("size"))
				   isize = attribute.getValue();
				if (attribute.getName().toString().equals("url"))
				   iurl = attribute.getValue();
			}
			movie.AddImage(itype,isize,iurl);
		} else if (tag.equalsIgnoreCase("person")) {
			String name = null;
			String job = null;
			String character = null;
			String url = null;
			String thumb = null;
			Iterator<Attribute> attributes = se.getAttributes();
			while (attributes.hasNext()) {
				Attribute attribute = attributes.next();
				if (attribute.getName().toString().equals("name"))
				   name = attribute.getValue();
				if (attribute.getName().toString().equals("job"))
				   job = attribute.getValue();
				if (attribute.getName().toString().equals("character"))
				   character = attribute.getValue();
				if (attribute.getName().toString().equals("url"))
				   url = attribute.getValue();
				if (attribute.getName().toString().equals("thumb"))
				   thumb = attribute.getValue();

			}
			movie.AddCast(name, job, character, url, url);
		}
	    } else if (event.isEndElement()) {
		if (event.toString().equalsIgnoreCase("</movies>")) {
		    break;
		}
	    }
	}
	return movie;
}
}
